/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package se.kth.lwr.jeat.core;

import java.util.*;

/**
 * A base class for representation of all traceable background data for the model.
 * All data used in the Model needs to be wrapped into a DataSource objects in 
 * order to be traceable and mutable from outside the a generic expression. 
 * </p> In the Model the value is then accessed through its 
 * {@link useValue(Inventoriable user)} method, which recording usage if the data.
 *
 * @author david
 */
public abstract class DataSource<V> extends Described implements Reportable{

    //a reference to all existing DataSources
    private static HashSet<DataSource> sources = new HashSet<>();
    //a reference to all users of this DataSoruce
    private Set<Activity> users = new HashSet<>();
    //reference to the value of this DataSource
    private V value;
    
    
    /**Creates a hidden DataSource Object(not added to the static list of 
     * data sources) without initial value.
     * 
     * @param name name of the source
     * @param description description of the source
     */
    
    protected DataSource(String name, String description) {
        super(name, description);
        value=null;
        
    }
    
    

    /**
     * Creates a DataSource Object that will be added to the static list of 
     * sources.
     *
     * @param name The name of the DataSource
     * @param description The description of the DataSource
     * @param value The value of the DataSource
     */
    public DataSource(String name, String description, V value) {
        super(name, description);
        sources.add(this);
        this.value = value;
    }

    /**
     * Returns all existing DataSources (used and unused)
     *
     * @return a Set containing all existing DataSources
     */
    public static Set<DataSource> getDataSources() {
        return Collections.unmodifiableSet(sources);
    }

    /**
     * Returns all Activities that uses this DataSource
     *
     * @return a Set of Activities that are in use of this DataSource
     */
    public Set<Activity> getUsers() {
        Set<Activity> retval=Collections.unmodifiableSet(users);
        return retval;
    }

    /**
     * Uses the value of this DataSource. This method does the following: <ul>
     * <li>adds the user to a list of users in this DataSource</li> <li>adds the
     * source to a list of used sources in the passed Activity</li> <li>returns
     * the value of the DataSource</li> </ul>
     *
     * @param user The activity that uses the value of the DataSource
     * @return the Value of the DataSource
     */
    public V useValue(Activity user) {
        users.add(user);
        user.addSource(this);
        return value;
    }
    
    /**Returns the value of this data source without recording the usage. Never use 
     * this method if the model actually uses the value for calculations. In such
     * cases use {@link DataSource.useValue()} instead.
     * 
     * @return The value of this data source
     */
    

    public V readValue(){
        return value;
    }

    /**
     * Reports the value of the source as one or several data rows. Each row 
     * consists of four fields: key, value, unit, comment. Den här funktionen
     * tillkom för att göra det möjligt att rapportera värdet av för mig okända
     * datakällor.
     *
     * @return a Set of ValueRecords that defines the value of this data source
     */
    public Report getReport() {
        Report report=new Report();
        report.addRow("["+this.getClass().getSimpleName()+"]", "["+readValue().getClass().getSimpleName()+"]","not available", this.getDescription());
        return report;
    }
    
    
    
    

}
